@inherits MiniRazor.TemplateBase<CodeEntity>
@namespace OSharp.CodeGeneration.Templates
@using System;
@using System.Collections.Generic;
@using System.Linq;
@using OSharp.CodeGeneration.Services.Entities
@using OSharp.CodeGeneration.Utils
@using OSharp.Collections;
@using OSharp.Exceptions;
@using OSharp.Extensions;
@{
  CodeEntity entity = Model;
  string keyType = TypeHelper.ToSingleTypeName(entity.PrimaryKeyTypeFullName);
  List<string> addNamespaces = entity.Properties.Where(m => m.RelateEntity != null).Select(m => TypeHelper.GetNamespace(m.RelateEntity))
    .Union(entity.Properties.Where(m => m.TypeName.Contains(".") && !m.TypeName.StartsWith("System.")).Select(m => TypeHelper.GetNamespace(m.TypeName)))
    .Distinct().Where(m => m != entity.Module.Namespace + ".Entities").ToList();
}//------------------------------------------------------------------------------
// <auto-generated>
//    此代码由代码生成器生成。
//    手动更改此文件可能导致应用程序出现意外的行为。
//    如果重新生成代码，对此文件的任何修改都会丢失。
//    如果需要扩展此类：可遵守如下规则进行扩展：
//      1.横向扩展：如需添加额外的属性，可新建文件“@(entity.Name).cs”的分部类“public partial class @(entity.Name)”添加属性
// </auto-generated>
//
// <copyright file="@(entity.Name).generated.cs" company="@entity.Module.Project.Company">
//     @entity.Module.Project.Copyright
// </copyright>
// <site>@entity.Module.Project.SiteUrl</site>
// <last-editor>@entity.Module.Project.Creator</last-editor>
// -----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

using OSharp.Entity;

@foreach (var space in addNamespaces)
{
<text>using @(space);</text>
}

namespace @(entity.Module.Namespace).Entities
{
    /// &lt;summary&gt;
    /// 实体类：@(entity.Display)信息
    /// &lt;/summary&gt;
    [Description("@(entity.Display)信息")]
    [TableNamePrefix("@(entity.Module.Name)")]
    public partial class @entity.Name : @(GetInterfaces(entity, keyType))
    {
@foreach (var prop in entity.Properties.OrderBy(m => m.IsForeignKey || m.IsNavigation))
{
<text>        /// &lt;summary&gt;
        /// 获取或设置 @prop.Display
        /// &lt;/summary&gt;
        [@GetAttributes(prop)]
        public @GetProperty(prop)

</text>
}
@if (entity.HasLocked)
{
<text>        /// <summary>
        /// 获取或设置 是否锁定
        /// </summary>
        [DisplayName("是否锁定")]
        public bool IsLocked { get; set; }

</text>
}
@if (entity.HasSoftDeleted)
{
<text>        /// <summary>
        /// 获取或设置 数据逻辑删除时间，为null表示正常数据，有值表示已逻辑删除，同时删除时间每次不同也能保证索引唯一性
        /// </summary>
        [DisplayName("删除时间")]
        public DateTime? DeletedTime { get; set; }

</text>
}
@if (entity.HasCreatedTime || entity.HasCreationAudited)
{
<text>        /// <summary>
        /// 获取或设置 创建时间
        /// </summary>
        [DisplayName("创建时间")]
        public DateTime CreatedTime { get; set; }

</text>
}
@if (entity.HasCreationAudited)
{
<text>        /// <summary>
        /// 获取或设置 创建者编号
        /// </summary>
        [DisplayName("创建者编号")]
        public @(keyType)? CreatorId { get; set; }

</text>
}
@if (entity.HasUpdateAudited) {
<text>        /// <summary>
        /// 获取或设置 更新者编号
        /// </summary>
        [DisplayName("更新者编号")]
        public @(keyType)? LastUpdaterId { get; set; }

        /// <summary>
        /// 获取或设置 最后更新时间
        /// </summary>
        [DisplayName("更新时间")]
        public DateTime? LastUpdatedTime { get; set; }

</text>
}
    }
}

@functions
{

    static string GetInterfaces(CodeEntity entity, string keyType)
    {
      List<string> list = new List<string>();

      list.Add(string.Format("EntityBase<{0}>", keyType));
      list.AddIf("ILockable", entity.HasLocked);
      list.AddIf("ISoftDeletable", entity.HasSoftDeleted);
      list.AddIf("ICreatedTime", entity.HasCreatedTime);
      list.AddIf("ICreationAudited<int>", entity.HasCreationAudited);
      list.AddIf("IUpdateAudited<int>", entity.HasUpdateAudited);

      return list.ExpandAndToString(", ");
    }

    static string GetAttributes(CodeProperty prop)
    {
      List<string>list = new List<string>();
      list.Add(string.Format("DisplayName(\"{0}\")", prop.Display));
      if (prop.TypeName == "System.String")
      {
        if (prop.IsRequired != null && prop.IsRequired.Value)
        {
          list.Add("Required");
        }
        if (prop.MaxLength > 0)
        {
          string min = prop.MinLength > -1 ? string.Format(", MinimumLength = {0}", prop.MinLength.Value) : "";
          list.Add(string.Format("StringLength({0}{1})", prop.MaxLength.Value, min));
        }
      }
      if (!string.IsNullOrEmpty(prop.DataAuthFlag))
      {
        list.Add(prop.DataAuthFlag);
      }

      return list.ExpandAndToString(", ");
    }

    static string GetProperty(CodeProperty prop)
    {
      string propName = $"{prop.Entity.Module.Name}.{prop.Entity.Name}.{prop.Name}";
      List<string>list = new List<string>();

      //导航属性，添加virtual
      if (prop.IsNavigation)
      {
        list.Add("virtual");
      }
      //属性类型
      string propType = TypeHelper.ToSingleTypeName(prop.TypeName);
      if (propType == "ICollection<>")
      {
        if (prop.RelateEntity.IsNullOrEmpty())
        {
          throw new OsharpException($"属性“{propName}”类型为“ICollection<>”的导航属性，关联实体不能为空");
        }
        propType = string.Format($"ICollection<{TypeHelper.ToSingleTypeName(prop.RelateEntity)}>");
      }
      //可空的值类型，添加?符号
      Type tmpType = Type.GetType(prop.TypeName);
      if (prop.IsNullable && tmpType is {IsValueType: true })
      {
        propType += "?";
      }
      list.Add(propType);
      list.Add(prop.Name);
      list.Add("{ get; set; }");

      if (propType == "ICollection<>")
      {
        list.Add(string.Format("= new List<{0}>();", TypeHelper.ToSingleTypeName(prop.RelateEntity)));
      }

      return list.ExpandAndToString(" ");
    }

}
